## Civcraft: SC Mod Specialized Python Functions
# Functions in this file have to do with production, be it unit, building,
# building-unit, addon, etc.

from CvPythonExtensions import *
import CvUtil

# globals
gc = CyGlobalContext()

# 
# Creates the unit building in the plot that a building has started building
# with the correct amount of HP to start with.
# argsList:
# pCity: CyCity object of where the new unit building will be created.
# eBuildingType: The enumerated bulding type. Should be a BuildingTypes enumerated value.
#
def setUnitBuildingOnStartBuildingProduction(pCity, eBuildingType):
    pPlayer = CyGlobalContext().getPlayer(pCity.getOwner())
    eUnitID = gc.getCivilizationInfo( pPlayer.getCivilizationType() ).getCivilizationUnits( gc.getBuildingInfo(eBuildingType).getBuildingUnitAssociation() )

    pNewUnit = pPlayer.initUnit(eUnitID, pCity.getX(), pCity.getY(), UnitAITypes.NO_UNITAI)
    pNewUnit.setHitPoints(getUnitBuildingConstructionHPPerTurn(eUnitID, eBuildingType))
    pNewUnit.setShields(getUnitBuildingConstructionHPPerTurn(eUnitID, eBuildingType))
    


#
# Updates the unit building in the plot with HP for one turn of building.
# pUnit: CyUnit object of the unit to update
#
def updateUnitBuildingConstructionTurnHP(pUnit, eBuilding):
    # Some basic checking
    if (pUnit == None):
        CvUtil.pyAssert( False, "pUnit is None in updateUnitBuildingConstructionTurnHP" )
        return

    pPlayer = gc.getPlayer( pUnit.getOwner() )
    pCity = pUnit.plot().getPlotCity()
    pUnitInfo = gc.getUnitInfo(pUnit.getUnitType())

    CvUtil.pyAssert( pPlayer != None, "updateUnitBuildingConstructionTurnsHP found a building unit with no owner!" )
    CvUtil.pyAssert( pCity != None, "updateUnitBuildingConstructionTurnsHP found a building unit with no city!" )

    # Check how many turns are left to build this building unit.
    iTotalTurnsToBuild = gc.getBuildingInfo(eBuilding).getProductionCost() / getBuildDenomination()

    # If the player is not cheating with fast builds...
    if (not pPlayer.isCheatEnabled(CheatTypes.CHEAT_FAST_BUILD) ):
        # If there is more than one turn left, just add the normal amount.
        if (pCity.getProductionTurnsLeft() > 1):
            pUnit.changeHitPoints(getUnitBuildingConstructionHPPerTurn( pUnit.getUnitType(), eBuilding  ))
            pUnit.changeShields(getUnitBuildingConstructionShieldsPerTurn( pUnit.getUnitType(), eBuilding  ))
        else:
            # If there is only one turn left, we are either at the maximum allounce of building
            # HP and Shields, or we're just under (because of roundoff from dividing hitPoints/turnsToBuild
            # or shields/turnsToBuild. So, just give the remaining, if needed.
            pUnit.changeHitPoints(getUnitBuildingConstructionHPFinalTurn( pUnit.getUnitType(), eBuilding ))
            pUnit.changeShields(getUnitBuildingConstructionShieldsFinalTurn( pUnit.getUnitType(), eBuilding  ))

    # If the player is using the fast build cheat, than just give them the rest of the health that the building
    # hasn't recieved yet.
    else:
        # Find how many legitimate turns of constructing we've done, and how many more need to happen.
        iTurnsBeforeCheat = pCity.getProduction() / getBuildDenomination()
        iTurnsNeeded = iTotalTurnsToBuild - iTurnsBeforeCheat - 1 # One turn will be handled by the lastTurn functions.

        iHP = getUnitBuildingConstructionHPPerTurn(pUnit.getUnitType(), eBuilding) * iTurnsNeeded
        iHP += getUnitBuildingConstructionHPFinalTurn(pUnit.getUnitType(), eBuilding)
        iShields = getUnitBuildingConstructionShieldsPerTurn(pUnit.getUnitType(), eBuilding) * iTurnsNeeded
        iShields += getUnitBuildingConstructionShieldsFinalTurn(pUnit.getUnitType(), eBuilding)
        
        pUnit.changeHitPoints(iHP)
        pUnit.changeShields(iShields)



#
# Some functions to help the two above.
#

#
# Returns the build denomination. Also does checking to make sure it exists.
def getBuildDenomination():
    iDenom = gc.getDefineINT("BUILD_DENOMINATION")
    CvUtil.pyAssert(iDenom > 0, "Build denomination not set! Found in CivcraftSCProduction." )
    return iDenom

#
# Returns how much HP a building should "heal" during a single construction turn.
#
def getUnitBuildingConstructionHPPerTurn(eUnit, eBuilding):
    if (eUnit == None):
        return 0

    pUnitInfo = gc.getUnitInfo(eUnit)
    pBuildingInfo = gc.getBuildingInfo(eBuilding)
    
    iMaxHitPoints = pUnitInfo.getHitPoints()
    iTotalTurnsToBuild = pBuildingInfo.getProductionCost() / getBuildDenomination()
    
    return iMaxHitPoints / iTotalTurnsToBuild

#
# Returns how many shields a building should "heal" during a single construction turn.
#
def getUnitBuildingConstructionShieldsPerTurn(eUnit, eBuilding):
    if (eUnit == None):
        return 0

    pUnitInfo = gc.getUnitInfo(eUnit)
    pBuildingInfo = gc.getBuildingInfo(eBuilding)

    iMaxShields = pUnitInfo.getShields()
    iTotalTurnsToBuild = pBuildingInfo.getProductionCost() / getBuildDenomination()
    return iMaxShields / iTotalTurnsToBuild

#
# Returns how many hit points a building should "heal" during their last construction turn.
#
def getUnitBuildingConstructionHPFinalTurn(eUnit, eBuilding):
    if (eUnit == None):
        return 0

    pUnitInfo = gc.getUnitInfo(eUnit)
    pBuildingInfo = gc.getBuildingInfo(eBuilding)

    iHitPointsPerTurn = getUnitBuildingConstructionHPPerTurn(eUnit, eBuilding)
    iTotalTurnsToBuild = pBuildingInfo.getProductionCost() / getBuildDenomination()

    return pUnitInfo.getHitPoints() - (iHitPointsPerTurn * iTotalTurnsToBuild)

#
# Returns how many shields a building should "heal" during their last construction turn.
#
def getUnitBuildingConstructionShieldsFinalTurn(eUnit, eBuilding):
    if (eUnit == None):
        return 0

    pUnitInfo = gc.getUnitInfo(eUnit)
    pBuildingInfo = gc.getBuildingInfo(eBuilding)

    iShieldsPerTurn = getUnitBuildingConstructionShieldsPerTurn(eUnit, eBuilding)
    iTotalTurnsToBuild = pBuildingInfo.getProductionCost() / getBuildDenomination()

    return pUnitInfo.getShields() - (iShieldsPerTurn * iTotalTurnsToBuild)



            
